<template>
  <div class="traces">
    <header class="mb-8">
      <h1 class="glow-text">链路追踪</h1>
      <div class="tech-line mt-2"></div>
    </header>

    <!-- 上传链路数据表单 -->
    <div class="card mb-8" v-if="showUploadForm">
      <h2 class="text-xl font-medium mb-4">上传链路数据</h2>

      <div class="mb-4">
        <label class="block text-light-dark mb-2">请求定义</label>
        <textarea
          v-model="requestDefinition"
          class="input w-full h-32 font-mono text-sm"
          placeholder="请输入请求定义 (JSON 格式)"
        ></textarea>
      </div>

      <div class="mb-4">
        <label class="block text-light-dark mb-2">链路数据</label>
        <div class="flex items-center mb-2">
          <input
            type="file"
            ref="fileInput"
            class="hidden"
            accept=".json"
            @change="handleFileUpload"
          />
          <button @click="fileInput?.click()" class="btn btn-outline mr-2">
            选择文件
          </button>
          <span v-if="selectedFile" class="text-light-dark">
            已选择: {{ selectedFile.name }}
          </span>
        </div>
        <textarea
          v-model="traceData"
          class="input w-full h-64 font-mono text-sm"
          placeholder="请输入链路数据 (JSON 格式) 或上传 JSON 文件"
        ></textarea>
      </div>

      <div class="flex justify-end">
        <button @click="showUploadForm = false" class="btn btn-outline mr-2">取消</button>
        <button @click="uploadTrace" class="btn btn-primary" :disabled="uploading">
          <span v-if="uploading">上传中...</span>
          <span v-else>上传</span>
        </button>
      </div>
    </div>

    <!-- 链路列表 -->
    <div class="card">
      <div class="flex justify-between items-center mb-6">
        <h2 class="text-xl font-medium">链路列表</h2>
        <button @click="showUploadForm = true" class="btn btn-primary">
          <svg class="w-5 h-5 mr-2 inline-block" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
          </svg>
          上传链路数据
        </button>
      </div>

      <div v-if="loading" class="flex justify-center items-center py-12">
        <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary"></div>
      </div>

      <div v-else-if="traces.length === 0" class="text-center py-12 text-light-dark">
        暂无链路数据，请上传链路数据
      </div>

      <div v-else>
        <div class="overflow-x-auto">
          <table class="w-full">
            <thead>
              <tr class="border-b border-dark-light">
                <th class="py-3 px-4 text-left">ID</th>
                <th class="py-3 px-4 text-left">服务数量</th>
                <th class="py-3 px-4 text-left">Span 数量</th>
                <th class="py-3 px-4 text-left">创建时间</th>
                <th class="py-3 px-4 text-left">操作</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="trace in traces"
                :key="trace._id"
                class="border-b border-dark-light hover:bg-dark-darker"
              >
                <td class="py-3 px-4 font-mono">{{ trace._id }}</td>
                <td class="py-3 px-4">{{ trace.service_count }}</td>
                <td class="py-3 px-4">{{ trace.span_count }}</td>
                <td class="py-3 px-4">{{ formatDate(trace.created_at) }}</td>
                <td class="py-3 px-4">
                  <button
                    @click="viewTrace(trace._id)"
                    class="text-primary hover:text-primary-light mr-2"
                    title="查看详情"
                  >
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
                    </svg>
                  </button>
                  <button
                    @click="deleteTrace(trace._id)"
                    class="text-accent-pink hover:text-accent-pink/80"
                    title="删除"
                  >
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
                    </svg>
                  </button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <!-- 分页 -->
        <div class="flex justify-between items-center mt-6">
          <div class="text-light-dark">
            共 {{ pagination.total }} 条记录，第 {{ pagination.page }} / {{ pagination.pages }} 页
          </div>
          <div class="flex space-x-2">
            <button
              @click="changePage(pagination.page - 1)"
              class="btn btn-outline py-1 px-3"
              :disabled="pagination.page <= 1"
            >
              上一页
            </button>
            <button
              @click="changePage(pagination.page + 1)"
              class="btn btn-outline py-1 px-3"
              :disabled="pagination.page >= pagination.pages"
            >
              下一页
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 链路详情弹窗 -->
    <div v-if="selectedTrace" class="fixed inset-0 bg-dark-darker bg-opacity-75 flex items-center justify-center z-50">
      <div class="bg-dark-light rounded-lg w-full max-w-6xl max-h-[90vh] overflow-y-auto cyber-border">
        <div class="p-6">
          <div class="flex justify-between items-start mb-6">
            <h2 class="text-2xl font-bold">链路详情</h2>
            <button @click="selectedTrace = null" class="text-light-dark hover:text-primary">
              <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
              </svg>
            </button>
          </div>

          <div class="mb-6">
            <h3 class="text-lg font-medium mb-2">基本信息</h3>
            <div class="card bg-dark-darker p-4">
              <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                  <div class="text-light-dark mb-1">链路 ID:</div>
                  <div class="font-mono">{{ selectedTrace._id }}</div>
                </div>
                <div>
                  <div class="text-light-dark mb-1">创建时间:</div>
                  <div>{{ formatDate(selectedTrace.created_at) }}</div>
                </div>
              </div>
            </div>
          </div>

          <div class="mb-6">
            <h3 class="text-lg font-medium mb-2">请求定义</h3>
            <div class="card bg-dark-darker p-4 font-mono text-sm overflow-x-auto">
              <pre>{{ JSON.stringify(selectedTrace.request_definition, null, 2) }}</pre>
            </div>
          </div>

          <div class="mb-6">
            <h3 class="text-lg font-medium mb-2">服务拓扑</h3>
            <div class="card bg-dark-darker p-4 h-64" ref="topologyContainer">
              <!-- 拓扑图将在这里渲染 -->
              <div v-if="loadingTopology" class="flex justify-center items-center h-full">
                <div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary"></div>
              </div>
              <div v-else-if="!topology.length" class="flex justify-center items-center h-full text-light-dark">
                暂无拓扑数据
              </div>
            </div>
          </div>

          <div class="mb-6">
            <h3 class="text-lg font-medium mb-2">服务列表</h3>
            <div class="card bg-dark-darker p-4">
              <div v-if="loadingServices" class="flex justify-center items-center py-8">
                <div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary"></div>
              </div>
              <div v-else-if="!services.length" class="text-center py-8 text-light-dark">
                暂无服务数据
              </div>
              <div v-else class="overflow-x-auto">
                <table class="w-full">
                  <thead>
                    <tr class="border-b border-dark">
                      <th class="py-2 px-4 text-left">服务 ID</th>
                      <th class="py-2 px-4 text-left">服务名称</th>
                      <th class="py-2 px-4 text-left">操作</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr
                      v-for="service in services"
                      :key="service._id"
                      class="border-b border-dark"
                    >
                      <td class="py-2 px-4 font-mono text-sm">{{ service._id }}</td>
                      <td class="py-2 px-4">{{ service.service_name }}</td>
                      <td class="py-2 px-4">
                        <button
                          @click="viewServiceRequests(service._id)"
                          class="text-primary hover:text-primary-light"
                        >
                          查看请求
                        </button>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>

          <div v-if="selectedService" class="mb-6">
            <h3 class="text-lg font-medium mb-2">服务请求信息</h3>
            <div class="card bg-dark-darker p-4">
              <div v-if="loadingRequests" class="flex justify-center items-center py-8">
                <div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary"></div>
              </div>
              <div v-else>
                <div class="mb-6">
                  <h4 class="text-md font-medium mb-2">入口请求 (Ingress)</h4>
                  <SimpleRequestList
                    :requests="ingressRequests"
                    :loading="loadingRequests"
                    empty-text="暂无入口请求"
                  />
                </div>

                <div>
                  <h4 class="text-md font-medium mb-2">出口请求 (Egress)</h4>
                  <SimpleRequestList
                    :requests="egressRequests"
                    :loading="loadingRequests"
                    empty-text="暂无出口请求"
                  />
                </div>
              </div>
            </div>
          </div>

          <div class="flex justify-end">
            <button @click="selectedTrace = null" class="btn btn-outline">关闭</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useRouter } from 'vue-router';
import { tracesApi } from '../api';

// 定义类型
interface Trace {
  _id: string;
  request_definition: any;
  trace_data: any[];
  service_count: number;
  span_count: number;
  created_at: string;
  updated_at: string;
}

interface Service {
  _id: string;
  trace_id: string;
  service_name: string;
  created_at: string;
}

interface TopologyLink {
  source: string;
  target: string;
}

interface Request {
  _id: string;
  service_id: string;
  request_type: 'ingress' | 'egress';
  method: string;
  url: string;
  created_at: string;
}

interface ServiceRequests {
  ingress: Request[];
  egress: Request[];
}

interface Pagination {
  page: number;
  page_size: number;
  total: number;
  pages: number;
}

// 状态变量
const showUploadForm = ref(false);
const requestDefinition = ref('{}');
const traceData = ref('');
const selectedFile = ref<File | null>(null);
const uploading = ref(false);
const loading = ref(false);
const traces = ref<Trace[]>([]);
const pagination = ref<Pagination>({
  page: 1,
  page_size: 10,
  total: 0,
  pages: 1
});

// 详情相关状态
const selectedTrace = ref<Trace | null>(null);
const loadingTopology = ref(false);
const topology = ref<TopologyLink[]>([]);
const loadingServices = ref(false);
const services = ref<Service[]>([]);
const selectedService = ref<string | null>(null);
const loadingRequests = ref(false);
const serviceRequests = ref<ServiceRequests>({
  ingress: [],
  egress: []
});

// 计算属性
const ingressRequests = computed(() => {
  if (!serviceRequests.value || !serviceRequests.value.ingress) return [];
  return serviceRequests.value.ingress;
});

const egressRequests = computed(() => {
  if (!serviceRequests.value || !serviceRequests.value.egress) return [];
  return serviceRequests.value.egress;
});

// 文件输入引用
const fileInput = ref<HTMLInputElement | null>(null);

// 处理文件上传
const handleFileUpload = (event: Event) => {
  const target = event.target as HTMLInputElement;
  if (!target.files || !target.files.length) return;

  const file = target.files[0];
  if (!file) return;

  selectedFile.value = file;

  const reader = new FileReader();
  reader.onload = (e: ProgressEvent<FileReader>) => {
    try {
      if (e.target && e.target.result) {
        const content = e.target.result as string;
        traceData.value = content;
      }
    } catch (error) {
      console.error('文件读取失败:', error);
      alert('文件读取失败，请确保上传的是有效的 JSON 文件');
    }
  };
  reader.readAsText(file);
};

// 上传链路数据
const uploadTrace = async () => {
  try {
    // 验证输入
    if (!traceData.value) {
      alert('请输入链路数据或上传 JSON 文件');
      return;
    }

    let traceDataObj;
    let requestDefinitionObj;

    try {
      traceDataObj = JSON.parse(traceData.value);
      requestDefinitionObj = JSON.parse(requestDefinition.value);
    } catch (error) {
      alert('JSON 格式错误，请检查输入');
      return;
    }

    uploading.value = true;

    // 发送请求
    await tracesApi.create({
      request_definition: requestDefinitionObj,
      trace_data: traceDataObj
    });

    // 重置表单
    requestDefinition.value = '{}';
    traceData.value = '';
    selectedFile.value = null;
    showUploadForm.value = false;

    // 刷新列表
    fetchTraces();

    alert('链路数据上传成功');
  } catch (error: any) {
    console.error('上传链路数据失败:', error);
    alert(`上传链路数据失败: ${error.response?.data?.error || error.message}`);
  } finally {
    uploading.value = false;
  }
};

// 获取链路列表
const fetchTraces = async () => {
  try {
    loading.value = true;

    const response = await tracesApi.getAll({
      page: pagination.value.page,
      page_size: pagination.value.page_size
    });

    // 假设 API 返回的数据在 data 属性中
    const data = response.data || response;

    traces.value = data.traces || [];
    pagination.value = {
      page: data.page || 1,
      page_size: data.page_size || 10,
      total: data.total || 0,
      pages: data.pages || 1
    };
  } catch (error: any) {
    console.error('获取链路列表失败:', error);
    alert(`获取链路列表失败: ${error.response?.data?.error || error.message}`);
  } finally {
    loading.value = false;
  }
};

// 切换页码
const changePage = (page: number) => {
  if (page < 1 || page > pagination.value.pages) return;
  pagination.value.page = page;
  fetchTraces();
};

// 初始化路由
const router = useRouter();

// 查看链路详情
const viewTrace = (traceId: string) => {
  // 导航到链路详情页面
  router.push(`/traces/${traceId}`);
};

// 查看服务请求
const viewServiceRequests = async (serviceId: string) => {
  if (!serviceId) return;

  try {
    // 设置状态
    loadingRequests.value = true;
    selectedService.value = serviceId;

    // 重置数据
    serviceRequests.value = { ingress: [], egress: [] };

    // 等待一个帧
    await new Promise(resolve => setTimeout(resolve, 0));

    // 请求数据
    const response = await tracesApi.getServiceRequests(serviceId);

    // 处理数据
    if (response && typeof response === 'object') {
      const data = response as any;
      serviceRequests.value = {
        ingress: Array.isArray(data.ingress) ? data.ingress : [],
        egress: Array.isArray(data.egress) ? data.egress : []
      };
    }
  } catch (error: any) {
    console.error('获取服务请求失败:', error);
    // 不显示警告，避免影响用户体验
  } finally {
    loadingRequests.value = false;
  }
};

// 删除链路
const deleteTrace = async (traceId: string) => {
  if (!confirm('确定要删除该链路记录吗？此操作不可恢复。')) return;

  try {
    await tracesApi.delete(traceId);
    fetchTraces();
    alert('链路记录删除成功');
  } catch (error: any) {
    console.error('删除链路记录失败:', error);
    alert(`删除链路记录失败: ${error.response?.data?.error || error.message}`);
  }
};

// 格式化日期
const formatDate = (dateString: string) => {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleString('zh-CN');
};

// 不再需要渲染拓扑图
/* const renderTopology = () => {
  if (!topologyContainer.value || !topology.value.length) return;

  // 这里可以使用 AntV G6 或其他图形库渲染拓扑图
  // 由于我们没有直接引入 G6，这里只是一个简单的示例
  // 实际项目中应该使用 G6 或其他图形库

  const container = topologyContainer.value;
  if (!container) return;

  container.innerHTML = '';

  // 创建一个简单的 SVG 拓扑图
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('width', '100%');
  svg.setAttribute('height', '100%');
  svg.style.overflow = 'visible';

  // 计算节点位置
  const nodes = new Set<string>();
  topology.value.forEach(link => {
    nodes.add(link.source);
    nodes.add(link.target);
  });

  const nodeList = Array.from(nodes);
  const nodePositions: Record<string, { x: number; y: number }> = {};

  // 简单布局：将节点均匀分布在圆上
  const radius = Math.min(container.clientWidth, container.clientHeight) / 2 - 50;
  const centerX = container.clientWidth / 2;
  const centerY = container.clientHeight / 2;

  nodeList.forEach((node, index) => {
    const angle = (index / nodeList.length) * 2 * Math.PI;
    nodePositions[node] = {
      x: centerX + radius * Math.cos(angle),
      y: centerY + radius * Math.sin(angle)
    };
  });

  // 绘制连线
  topology.value.forEach(link => {
    const source = nodePositions[link.source];
    const target = nodePositions[link.target];

    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    line.setAttribute('x1', source.x.toString());
    line.setAttribute('y1', source.y.toString());
    line.setAttribute('x2', target.x.toString());
    line.setAttribute('y2', target.y.toString());
    line.setAttribute('stroke', '#3B82F6');
    line.setAttribute('stroke-width', '2');

    svg.appendChild(line);

    // 添加箭头
    const dx = target.x - source.x;
    const dy = target.y - source.y;
    const angle = Math.atan2(dy, dx);

    const arrowLength = 10;
    const arrowX = target.x - arrowLength * Math.cos(angle);
    const arrowY = target.y - arrowLength * Math.sin(angle);

    const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
    arrow.setAttribute('points', `
      ${target.x},${target.y}
      ${arrowX - arrowLength * Math.cos(angle - Math.PI/6)},${arrowY - arrowLength * Math.sin(angle - Math.PI/6)}
      ${arrowX - arrowLength * Math.cos(angle + Math.PI/6)},${arrowY - arrowLength * Math.sin(angle + Math.PI/6)}
    `);
    arrow.setAttribute('fill', '#3B82F6');

    svg.appendChild(arrow);
  });

  // 绘制节点
  nodeList.forEach(node => {
    const position = nodePositions[node];

    // 节点圆圈
    const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
    circle.setAttribute('cx', position.x.toString());
    circle.setAttribute('cy', position.y.toString());
    circle.setAttribute('r', '20');
    circle.setAttribute('fill', '#1E293B');
    circle.setAttribute('stroke', '#3B82F6');
    circle.setAttribute('stroke-width', '2');

    svg.appendChild(circle);

    // 节点文本
    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    text.setAttribute('x', position.x.toString());
    text.setAttribute('y', (position.y + 30).toString());
    text.setAttribute('text-anchor', 'middle');
    text.setAttribute('fill', '#F8FAFC');
    text.setAttribute('font-size', '12');
    text.textContent = node;

    svg.appendChild(text);
  });

  container.appendChild(svg);
}; */

// 生命周期钩子
onMounted(() => {
  fetchTraces();
});
</script>

<style scoped>
/* 可以添加组件特定的样式 */
</style>
